﻿package com.agileai.miscdp.hotweb.generator.standard;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.xml.sax.SAXException;

import com.agileai.miscdp.MiscdpPlugin;
import com.agileai.miscdp.hotweb.domain.ProjectConfig;
import com.agileai.miscdp.hotweb.domain.ResFileValueProvider;
import com.agileai.miscdp.hotweb.domain.standard.StandardFuncModel;
import com.agileai.miscdp.hotweb.generator.Generator;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.util.FileUtil;
import com.agileai.util.StringUtil;

import freemarker.ext.dom.NodeModel;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
 * Handler代码生成器
 */
public class SMHandlerGenerator implements Generator{
	private String charencoding = "UTF-8";
	private String templateDir = null;
	private File xmlFile = null;
	private String appName = null;
	private String listHandlerClassName;
	private String editHandlerClassName;
	private String srcPath = null;
	private StandardFuncModel funcModel = null;
	
	public void generate() {
		String fileName = "template";
        try {
        	templateDir = FileLocator.toFileURL(Platform.getBundle(MiscdpPlugin.getPluginId()).getResource(fileName)).getFile().toString();
        	
        	String listTemplateFile = "/standard/ListHandler.java.ftl";
        	generateListHandlerJavaFile(listTemplateFile,listHandlerClassName);
        	
        	String editTemplateFile = "/standard/EditHandler.java.ftl";
        	generateEditHandlerJavaFile(editTemplateFile,editHandlerClassName);
        	
        	if (funcModel.getResFileValueProvider() != null){
        		String templateFile = "/fileuploader/UploaderHandler.java.ftl";
        		generateUploaderHandler(templateFile);
        	}
        } catch (Exception e) {
        	MiscdpPlugin.getDefault().logError(e.getLocalizedMessage(), e);
        }		
	}
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void generateListHandlerJavaFile(String templateFile,String fullClassName) throws IOException, 
		SAXException, ParserConfigurationException, TemplateException{
    	Configuration cfg = new Configuration();
    	cfg.setEncoding(Locale.getDefault(), charencoding);
    	cfg.setDirectoryForTemplateLoading(new File(templateDir));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
    	Template temp = cfg.getTemplate(templateFile,charencoding);
    	temp.setEncoding(charencoding);
        Map root = new HashMap();
        NodeModel nodeModel = freemarker.ext.dom.NodeModel.parse(xmlFile);
        root.put("doc",nodeModel);
    	File javaFile = FileUtil.createJavaFile(srcPath, fullClassName);
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(javaFile),charencoding));
        temp.process(root, out);
        out.flush();
        MiscdpUtil.getJavaFormater().format(javaFile.getAbsoluteFile(), charencoding);
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void generateEditHandlerJavaFile(String templateFile,String fullClassName) throws IOException, 
		SAXException, ParserConfigurationException, TemplateException{
    	Configuration cfg = new Configuration();
    	cfg.setEncoding(Locale.getDefault(), charencoding);
    	cfg.setDirectoryForTemplateLoading(new File(templateDir));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
    	Template temp = cfg.getTemplate(templateFile,charencoding);
    	temp.setEncoding(charencoding);
        Map root = new HashMap();
        NodeModel nodeModel = freemarker.ext.dom.NodeModel.parse(xmlFile);
        root.put("doc",nodeModel);

        if (funcModel.getResFileValueProvider() != null){
        	HashMap resFileModel = new HashMap();
        	String primaryKey = funcModel.getPrimaryKey();
        	resFileModel.put("bizPrimaryKeyField", primaryKey);
        	root.put("resFileModel", resFileModel);
        }else{
        	root.put("resFileModel", "");
        }
        
    	File javaFile = FileUtil.createJavaFile(srcPath, fullClassName);
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(javaFile),charencoding));
        temp.process(root, out);
        out.flush();
        MiscdpUtil.getJavaFormater().format(javaFile.getAbsoluteFile(), charencoding);
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void generateUploaderHandler(String templateFile)throws IOException, 
		SAXException, ParserConfigurationException, TemplateException{
		
    	String tableName = funcModel.getTableName();
    	String prefixName = MiscdpUtil.getValidName(tableName);
    	
    	String resFileHandlerId = prefixName+"ResouceUploader";
        String handlerClassName = MiscdpUtil.parsePackage(funcModel.getEditHandlerClass())+"."+resFileHandlerId+"Handler";
        String serviceId = StringUtil.lowerFirst(MiscdpUtil.getValidName(tableName))+"ResourceUploadService";
        ProjectConfig projectConfig = MiscdpUtil.getProjectConfig(appName);
        String mainPkg = projectConfig.getMainPkg();
        
        ResFileValueProvider resFileValueProvider = funcModel.getResFileValueProvider();
        String primaryKey = resFileValueProvider.getPrimaryKeyField();
		Configuration cfg = new Configuration();
    	cfg.setEncoding(Locale.getDefault(), charencoding);
    	cfg.setDirectoryForTemplateLoading(new File(templateDir));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
    	Template temp = cfg.getTemplate(templateFile,charencoding);
    	temp.setEncoding(charencoding);
        Map root = new HashMap();
        HashMap model = new HashMap();
        model.put("handlerClass", handlerClassName);
        model.put("resFileServiceId", serviceId);
        model.put("mainPkg", mainPkg);
        
    	model.put("bizIdField", resFileValueProvider.getBizIdField());
    	model.put("resIdField", resFileValueProvider.getResIdField());
    	model.put("primaryKeyField", resFileValueProvider.getPrimaryKeyField());
        
        model.put("primaryKey", primaryKey);
        
        root.put("model",model);
    	File javaFile = FileUtil.createJavaFile(srcPath, handlerClassName);
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(javaFile),charencoding));
        temp.process(root, out);
        out.flush();
        MiscdpUtil.getJavaFormater().format(javaFile.getAbsoluteFile(), charencoding);
	}
	
	public void setListHandlerClassName(String listHandlerClassName) {
		this.listHandlerClassName = listHandlerClassName;
	}
	public void setEditHandlerClassName(String editHandlerClassName) {
		this.editHandlerClassName = editHandlerClassName;
	}
	public StandardFuncModel getFuncModel() {
		return funcModel;
	}
	public void setFuncModel(StandardFuncModel funcModel) {
		this.funcModel = funcModel;
	}
	public void setXmlFile(File xmlFile) {
		this.xmlFile = xmlFile;
	}
	public void setSrcPath(String srcPath) {
		this.srcPath = srcPath;
	}
	public void setAppName(String appName) {
		this.appName = appName;
	}
}